#include "fighter.h"
#include "fig_player_craft.h"
#include "fig_enemy_manager.h"
#include "fig_sfx_manager.h"
#include "fig_level.h"
#include "pvu_shadow.h"
#include "fig_sounds.h"
#include "fig_vars.h"
#include "fig_enemybullet_master.h"
#include "gen_game_state.h"
#include "fig_award_tracker.h"
#include "fig_constants.h"
#include "fig_ui_pausemenu.h"

#include "fig_gamecenter.h"


#include "fig_trophie_notification.h"

//#include "gamecenter/c_gamecenter_manager.h"
#include "resman/resman.h"

#include "gameflow/ui_popup.h"
#include "math/facing.h"
#include "application/game_script.h"
#include "console/console.h"
#include "ui/ui_manager.h"
#include "gameflow/game_flow_manager.h"
#include "dd/dd_man.h"
#include "font/font_manager.h"
#include "script/scripthelper.h"
#include "input/keyboard.h"
#include "graphics/graphics_util.h"
#include "luaplus/LuaObject.h"
#include "script/scripthelper.h"
#include "script/write_lua.h"
#include "lang/lang.h"
#include "vfs/vfs.h"
#include "script/file_list.h"
#include "num/rand.h"

#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging
#include "util/timer.h"		    // logging

#include <stdio.h>
#include <stdlib.h>// for MAX_PATH
//#include <direct.h> // for getcwd



using namespace script;


Fighter&	Fighter::Instance()
{
	static Fighter	Inst;
	return Inst;
}

Fighter::Fighter() : m_IsDebuuging(false),
					 m_pLevel(NULL),
					 m_Scale(0.5f),					 
					 m_FPS(0),
					 m_FPSTemp(0),
					 m_TestTime(0),
					 m_DebugOffsetY(0),
					 m_ControllerKeyDirX(0),
					 m_ControllerKeyDirY(0)
			
{
	
	m_Scale = (float)GetGraphics()->GetScreenWidth() / FIGConstants::TEXTURE_NATIVE_WIDTH;
	if( m_Scale > 0.999 && m_Scale < 1.0f)
		m_Scale = 1.0f;
	
	m_FPSCounter.SetLimit(1.0f);

}
Fighter::~Fighter()
{
	
	Clear();
}

void	Fighter::Clear()
{
	if(m_pLevel)
		m_pLevel->Clear();
}


void	Fighter::Render()
{
	
	//return;
	if(m_pLevel)
		m_pLevel->Render(m_Offset,m_Scale);
	
	FIGSFXManager::Instance().Render(m_Offset,m_Scale);


#ifdef _DEBUG
	FontManager::Instance().Print(math::Vec2(0.1f,0.05f), "%i", m_FPS+1);

	int Temp = (int)((m_DebugOffsetY + 1.0f) * 10.0f);
	int Temp2 = Temp / 10;
	int Temp3 = Temp % 10;

	FontManager::Instance().Print(math::Vec2(0.1f,0.1f), "Screen: %i.%i", Temp2,Temp3);

	//FontManager::Instance().Print(math::Vec2(0.1f,0.1f), "%f", util::Timer::Instance().FPS());

	//FontManager::Instance().Print(math::Vec2(0.1f,0.15f), "Score: %i", FIGAwardTracker::Instance().GetCurrentLevelScore());

	//FontManager::Instance().Print(math::Vec2(0.1f,0.2f), "Time: %i", (int)m_TestTime);
#endif



}

void	Fighter::PostRender()
{
	FIGSFXManager::Instance().PostRender(m_Offset,m_Scale);
}

void	Fighter::RenderShadow()
{
	
}


void	Fighter::RenderDebug()
{
	if(!m_IsDebuuging)
		return;

	if(m_pLevel)
		m_pLevel->RenderDebug(m_Offset,m_Scale);

}

void	Fighter::Tick(float dt)
{
	
#ifdef _DEBUG
    
    if(dt > 0)
    {
        m_TestTime += dt;
        m_FPSTemp++;
        m_FPSCounter.Tick(dt);
        if(m_FPSCounter.IsReady())
        {
            m_FPSCounter.Reset();
            m_FPS = m_FPSTemp;
            m_FPSTemp = 0;
        }
    }
#endif

		
	m_Offset = FIGPlayerCraft::Instance().GetPos();
	m_Offset = - math::Vec2( (m_Offset.x - 0.5f ) , 0);
	
	FIGSFXManager::Instance().Tick (dt);	
	m_Offset *= 0.3f;

	if(m_pLevel)
		m_pLevel->Tick(dt);
	m_DebugOffsetY += 0.05f * dt;

    if(dt > 0)
        FIGSounds::Instance().Tick(dt);

    FIGTrophieNotification::Instance().Tick(dt);
	FIGUIPauseMenu::Instance().Tick(dt);


	if( m_ControllerKeyDirX == 0 && m_ControllerKeyDirX == 0)
	{}
	else
	{
		FIGPlayerCraft::Instance().OnICadeMove(math::Vec2((float)m_ControllerKeyDirX,(float)m_ControllerKeyDirY));
	}
	m_ControllerKeyDirX = 0;
	m_ControllerKeyDirY = 0;

	
}
	
void	Fighter::LoadFromFile(const std::string& File)
{

}

void	Fighter::SaveToFile()
{	
			   
}

void	Fighter::KeyPressed(input::Keyboard::KEY* pKey)
{
 	switch(pKey->KeyID)
	{

#ifdef _DEBUG
		case KEY_D:
			m_IsDebuuging = !m_IsDebuuging;
		break;

		case KEY_L:
			((FIGVars*)FIGVars::Instance())->SetCurrentLevel(FIGConstants::LEVEL_LAST);			
			((FIGVars*)FIGVars::Instance())->SetMaxPlayableLevel(FIGConstants::LEVEL_LAST);
		break;

#endif


		case KEY_F5:
		{
			char	Buffer[256];
			sprintf(Buffer, "screenshots/ac_%f", util::Timer::Instance().GetTimeStamp());
			GetGraphics()->TakeScreenShot(Buffer);
		}
		break;


		default:
		break;
	}

	if(pKey->KeyID == KEY_T || pKey->KeyID == KEY_F || pKey->KeyID == KEY_M || pKey->KeyID == KEY_G )
	{
		FIGPlayerCraft::Instance().OnControllerBomb();	
	}

	if(pKey->KeyID == KEY_R || pKey->KeyID == KEY_N || pKey->KeyID == KEY_P || pKey->KeyID == KEY_V )
	{
		FIGPlayerCraft::Instance().OnControllerGuardian();
	}

}


void	Fighter::KeyDown(input::Keyboard::KEY* pKey)
{
	
	if(pKey->KeyID == KEY_A || pKey->KeyID == KEY_LEFT)
		m_ControllerKeyDirX = -1;		
			
	if(pKey->KeyID == KEY_W || pKey->KeyID == KEY_UP)   		
		m_ControllerKeyDirY = -1;			

	if(pKey->KeyID == KEY_X || pKey->KeyID == KEY_DOWN)
		m_ControllerKeyDirY = 1;

	if(pKey->KeyID == KEY_D || pKey->KeyID == KEY_RIGHT)
		m_ControllerKeyDirX = 1;

   

}

void	Fighter::OnMouseMove(const math::Vec2& From, const math::Vec2& To)
{
	FIGPlayerCraft::Instance().OnMouseMove(From,To);
	m_MousePos = To;
}	

void	Fighter::MouseButtonPressed(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
	
}





void	Fighter::MouseButtonReleased(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{
    FIGPlayerCraft::Instance().OnMouseUp(Pos);
}
	
void	Fighter::MouseButtonDown(input::Mouse::BUTTON_STATE* pKey, const math::Vec2& Pos)
{

}


void	Fighter::ShakeScreen(float Intensity)
{
	if(m_pLevel)
		m_pLevel->Shake(Intensity);
}


void		Fighter::GoToNextLevel()
{

	int IsFullVersion = FIGVars::Instance()->GetInt(FIGVars::VAR_NAMES_IS_FULL_VERSION);
	int CurrentLevel = ((FIGVars*)FIGVars::Instance())->GetCurrentLevel();

	if(CurrentLevel == FIGConstants::LEVEL_LAST)
	{
        
		if(FIGVars::Instance()->GetInt(FIGVars::VAR_NAMES_DIFFICULTY) == 1)
			FIGVars::Instance()->SetInt(FIGVars::VAR_NAMES_IS_HARD_PLAYABLE,1);

		// report score to gamecenter here
                                                                  

        int HighScore = FIGVars::Instance()->GetInt(FIGVars::VAR_NAMES_HIGHSCORE);
		//FIGGameCenter::m_pInst->ReportScore(HighScore);
		FIGPlayerCraft::Instance().ResetToDefault();
        FIGVars::Instance()->Save();
        
        // make sure settings.ui has created by our popupmanager
        FIGUIPopupAnimatorMgr::Instance().GetPopup(FIGUIPopupAnimatorMgr::POPUP_NAMES_SETTING);
        
        
	    gameflow::GameFlowManager::Instance().GetTransition().StartTransition("","credits" , "" , NULL);
		return;
	}

	CurrentLevel++; 	 
	((FIGVars*)FIGVars::Instance())->SetCurrentLevel(CurrentLevel);
	int MaxPlayableLevel = ((FIGVars*)FIGVars::Instance())->GetMaxPlayableLevel();
	if(CurrentLevel > MaxPlayableLevel)
		((FIGVars*)FIGVars::Instance())->SetMaxPlayableLevel(CurrentLevel);

	FIGVars::Instance()->Save();

	if(IsFullVersion == 0 && CurrentLevel == FIGConstants::PAY_VERSION_START )
	{
		// he can't continue playing anymore. ( he has to buy it)

		// report score to gamecenter here
        int HighScore = FIGVars::Instance()->GetInt(FIGVars::VAR_NAMES_HIGHSCORE);
		//FIGGameCenter::m_pInst->ReportScore(HighScore);

		gameflow::GameFlowManager::Instance().GetTransition().StartTransition("","level_select" , "" , NULL);
	
	}
	else
	{
		gameflow::GameFlowManager::Instance().GetTransition().StartTransition("","comic_menu" , "" , NULL);
	}
	
	FIGVars::Instance()->Save();
	m_TestTime = 0;
}


void		Fighter::PlayLevel(int LevelNumber)
{
	if(m_pLevel)
	{
		m_pLevel->Clear();
		//UTIL_SAFE_DELETE(m_pLevel);
	}

	std::string LevelName = "level_" + lang::Lang::FormatNumber(LevelNumber) + ".lua";

	if(!m_pLevel)
	{
		m_pLevel = new FIGLevel(
							"level_bg_main/" + LevelName,
							"level_bg/" + LevelName,
							"level_enemy/" + LevelName
							);
	}
	else
	{
		m_pLevel->Load(
						"level_bg_main/" + LevelName,
						"level_bg/" + LevelName,
						"level_enemy/" + LevelName
						);
	}


}

void	Fighter::ResetDebugValues(float LevelMovementDelaySec)
{
	m_FPS = 0;
	m_FPSTemp = 0;
	m_TestTime = 0;
	m_DebugOffsetY = 0;

	m_DebugOffsetY  = m_DebugOffsetY  - ( 0.05f * LevelMovementDelaySec );
}



